package com.gdteam.kernel.persistence;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.gdteam.kernel.Service;
import com.gdteam.kernel.domain.Domain;

/**
 * PersistencyUnitManager contract  Responsible for :</br>
 * <ul>
 * <li>PU initialization (EntityManagerFactory provider)</li>
 * <li>Tx Operations (begin, commit, rollback)</li>
 * <li>Dao Provider</li>
 * <li>EntityManager provider</li>
 * <li>CRUD operations against Domain model</li>
 * </ul>
 * @author erwan
 *
 */
public interface PersistencyUnitManager extends Service {
    
    String FQN = "com.gdteam.kernel.persistence";
	
    /**
     * Transaction begin method
     */
    void beginTx();
	
    /**
     * Transaction rollback operation
     */
    void rollBackTx();
	
    /**
     * Transaction commit method
     */
    void commitTx();
	
    /**
     * Domain Management session getter. Used for query / criteria search
     * operations, specific persistency layer operations
     * @return hibernate session bound to current transaction
     */
    Session getUtil();

    /**
     * Trigger saveOrUpdate operation on Domain. Newly instanciated transient
     * Domain should have its id set after save method is called, and persisted
     * into underlying RDBMS. triggers :
     * <ul>
     * <li>id generation</li>
     * <li>id set</li>
     * <li>SQL INSERT statement </li>
     * </ul>
     * @param model model to be persisted
     */
    void save(Domain model);

    /**
     * Update Operation, for explicit direct SQL update instruction execution
     * @param model model to be updated. Id is used in order to check for update
     * operation. if instance is currently associated to the session, state is analyed.
     */
    void update(Domain model);
    
    /**
     * Domain deletion, triggers SQL delete operation
     * @param model
     */
    void delete(Domain model);

    /**
     * FindByPk operation, based on model id
     * @param model
     * @return null if id is not set or domain not found
     */
    Domain get(Domain model);
	
    /**
     * FindByPk operation, against domain model.
     * @param model model instance to find
     * @param readonly set to true if domain is retrieved for consultation. Modifications won't be taken into account
     * @return null if pk is not set or domain not found, readonly instance otherwiser
     */
    Domain get(Domain model, Boolean readonly);
	
    /**
     * Factory getter
     * @return session factory, for eventual runtime meta data information
     */
    SessionFactory getFactory();
	
}
